home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Graphics / sKulpt / skulpt-src / win-src / MenuWProc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-27  |  37.9 KB  |  1,232 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11.  
  12. // Includes D3D
  13. #define  D3D_OVERLOADS
  14. #include <ddraw.h>
  15. #include <d3d.h>
  16. #include <d3dx.h>
  17.  
  18. // Includes utilitaires D3D
  19. #include "d3dmath.h"
  20. #include "d3dutil.h"
  21. #include "D3DEnum.h"
  22.  
  23. // Ids Resources
  24. #include "resource.h"
  25.  
  26. // Constantes
  27. #include "const.h"
  28.  
  29. // Types
  30. #include "types.h"
  31.  
  32. // Variables globales projet
  33. #include "vars.h"
  34.  
  35. // Prototypes fonctions autres modules
  36. #include "proto.h"
  37.  
  38. // Macros
  39. #include "macros.h"
  40.  
  41. // Sortir un résumé de la scène dans la fenêtre de trace
  42. void vDescribe(void)
  43. {
  44.     int iCnt,
  45.         iVertices = 0,
  46.         iSelectedVertices = 0,
  47.         iHiddenVertices = 0,
  48.         iTriangles = 0,
  49.         iHiddenTriangles = 0,
  50.         iEdges = 0,
  51.         iHiddenEdges = 0,
  52.         iLamps = 0,
  53.         iSelectedLamps = 0,
  54.         iLitLamps = 0,
  55.         iObjects = 0,
  56.         iSelectedObjects = 0,
  57.         iHiddenObjects = 0,
  58.         iMaterials = 0;
  59.  
  60.     vTrace("*** Résumé scène courante :");
  61.  
  62.     // Compter les points
  63.     for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  64.         if (Vertices[iCnt].bEnabled)
  65.         {
  66.             iVertices++;
  67.             if (bIsVertexSelected(iCnt)) iSelectedVertices++;
  68.             if (Vertices[iCnt].bHidden) iHiddenVertices++;
  69.         }
  70.  
  71.     // Compter les lampes
  72.     for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  73.         if (Lampes[iCnt].bEnabled)
  74.         {
  75.             iLamps++;
  76.             if (Lampes[iCnt].bSelected) iSelectedLamps++;
  77.             if (Lampes[iCnt].bLit) iLitLamps++;
  78.         }
  79.  
  80.     // Compter les objets
  81.     for (iCnt = 0 ; iCnt <= iObjtLastUsed ; iCnt++)
  82.         if (Objects[iCnt].bEnabled)
  83.         {
  84.             iObjects++;
  85.             if (Objects[iCnt].bSelected) iSelectedObjects++;
  86.             if (Objects[iCnt].bHidden) iHiddenObjects++;
  87.         }
  88.  
  89.     // Compter les arêtes
  90.     for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
  91.         if (Edges[iCnt].bEnabled)
  92.         {
  93.             iEdges++;
  94.             if (Edges[iCnt].bHidden) iHiddenEdges++;
  95.         }
  96.  
  97.     // Compter les triangles
  98.     for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
  99.         if (Triangles[iCnt].bEnabled)
  100.         {
  101.             iTriangles++;
  102.             if (Triangles[iCnt].bHidden) iHiddenTriangles++;
  103.         }
  104.  
  105.         // Compter les matériaux
  106.     for (iCnt = 0 ; iCnt <= iMtrlLastUsed ; iCnt++)
  107.         if (Materials[iCnt].bEnabled)
  108.             iMaterials++;
  109.  
  110.     vTrace("Taille buffers en Ko : sommets %d, arêtes %d, triangles %d, objets D3D %d, matériaux %d, total %d.", sizeof(Vertices) / 1024, sizeof(Edges) / 1024, sizeof(Triangles) / 1024, sizeof(Objects) / 1024, sizeof(Materials) / 1024, (sizeof(Vertices) + sizeof(Edges) + sizeof(Triangles) + sizeof(Objects) + sizeof(Materials)) / 1024);
  111.     if (iVertices) vTrace("Points : %d (%d sélectionnés, %d cachés). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iVertices, iSelectedVertices, iHiddenVertices, iVertLastUsed, iVertFirstAvailable, 100 * ((iVertLastUsed + 1) - iVertices) / iVertices);
  112.     if (iEdges) vTrace("Arêtes : %d (%d cachées). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iEdges, iHiddenEdges, iEdgeLastUsed, iEdgeFirstAvailable, 100 * ((iEdgeLastUsed + 1) - iEdges) / iEdges);
  113.     if (iTriangles) vTrace("Triangles : %d (%d cachés, %d tracés par Direct3D). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iTriangles, iHiddenTriangles, iTriangles * 2, iTriaLastUsed, iTriaFirstAvailable, 100 * ((iTriaLastUsed + 1) - iTriangles) / iTriangles);
  114.     if (iObjects) vTrace("Objets : %d (%d sélectionnés, %d cachés). Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iObjects, iSelectedObjects, iHiddenObjects, iObjtLastUsed, iObjtFirstAvailable, 100 * ((iObjtLastUsed + 1) - iObjects) / iObjects);
  115.     if (iLamps) vTrace("Lampes : %d (%d sélectionnées, %d allumées). Dernière utilisée : %d, premier dispo : %d (frag : %d%%)", iLamps, iSelectedLamps, iLitLamps, iLampLastUsed, iLampFirstAvailable, 100 * ((iLampLastUsed + 1) - iLamps) / iLamps);
  116.     if (iMaterials) vTrace("Matériaux : %d. Dernier utilisé : %d, premier dispo : %d (frag : %d%%)", iMaterials, iMtrlLastUsed, iMtrlFirstAvailable, 100 * ((iMtrlLastUsed + 1) - iMaterials) / iMaterials);
  117. }
  118.  
  119. // Redimensionner la triview
  120. void vRemakeTriview(LPARAM lParam)
  121. {
  122.     HDC hdcScreen;
  123.     int iScreenWidth, iScreenHeight;
  124.  
  125.     if (!lParam)
  126.     {
  127.         hdcScreen = GetDC(NULL);
  128.         iScreenWidth = GetDeviceCaps(hdcScreen, HORZRES);
  129.         iScreenHeight = GetDeviceCaps(hdcScreen, VERTRES);
  130.     }
  131.     else
  132.     {
  133.         iScreenWidth = LOWORD(lParam);
  134.         iScreenHeight = HIWORD(lParam);
  135.     }
  136.  
  137.     vTrace("Réorganisation des fenêtres (écran %d x %d)", iScreenWidth, iScreenHeight);
  138.  
  139.     MoveWindow(hWndMenu, 0, 0, iScreenWidth, iScreenHeight / 9, TRUE);
  140.     MoveWindow(hWndPersp, iScreenWidth/2, iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  141.     MoveWindow(hWndTop, 0, iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  142.     MoveWindow(hWndFace, 0, 5 * iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  143.     MoveWindow(hWndRight, iScreenWidth/2, 5 * iScreenHeight / 9, iScreenWidth/2, 4 * iScreenHeight / 9, TRUE);
  144.  
  145.     if (!lParam) ReleaseDC(NULL, hdcScreen);
  146. }
  147.  
  148. // Mettre à jour les menus en fonction des variables de mode courant
  149. void vUpdateMenu(void)
  150. {
  151.     HMENU hMenu = GetMenu(hWndMenu);
  152.     CheckMenuItem(hMenu, ID_EDITION_GRILLE, MF_BYCOMMAND | (bGrid ? MF_CHECKED : MF_UNCHECKED));
  153.     CheckMenuItem(hMenu, ID_EDITION_COORDONNES, MF_BYCOMMAND | (bCoords ? MF_CHECKED : MF_UNCHECKED));
  154.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_POINT, MF_BYCOMMAND | (dFillMode == D3DFILL_POINT ? MF_CHECKED : MF_UNCHECKED));
  155.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_FILDEFERF, MF_BYCOMMAND | (dFillMode == D3DFILL_WIREFRAME ? MF_CHECKED : MF_UNCHECKED));
  156.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_FACETTES, MF_BYCOMMAND | (dFillMode == D3DFILL_SOLID ? MF_CHECKED : MF_UNCHECKED));
  157.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_ZBUFFER, (dZBuf == D3DZB_TRUE ? MF_CHECKED : MF_UNCHECKED));
  158.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_TRANSPARENCEALPHABLENDING, (bAlpha ? MF_CHECKED : MF_UNCHECKED));
  159.     CheckMenuItem(hMenu, ID_OBSERVATEUR_MODE_ECLAIRAGESPCULAIRE, (bSpecular ? MF_CHECKED : MF_UNCHECKED));
  160.  
  161.     CheckMenuItem(hMenu, ID_OUTILS_AUCUN, MF_BYCOMMAND | MF_UNCHECKED);
  162.     CheckMenuItem(hMenu, ID_OUTILS_SLECTEUR, MF_BYCOMMAND | MF_UNCHECKED);
  163.     CheckMenuItem(hMenu, ID_OUTILS_DSLECTEUR, MF_BYCOMMAND | MF_UNCHECKED);
  164.     CheckMenuItem(hMenu, ID_OUTILS_AIMANT, MF_BYCOMMAND | MF_UNCHECKED);
  165.     CheckMenuItem(hMenu, ID_OUTILS_COURBE, MF_BYCOMMAND | MF_UNCHECKED);
  166.     CheckMenuItem(hMenu, ID_OUTILS_EXTRUDEUR, MF_BYCOMMAND | MF_UNCHECKED);
  167.     CheckMenuItem(hMenu, ID_OUTILS_ARTES, MF_BYCOMMAND | MF_UNCHECKED);
  168.     CheckMenuItem(hMenu, ID_OUTILS_PINCE, MF_BYCOMMAND | MF_UNCHECKED);
  169.  
  170.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_NONE, MF_BYCOMMAND | MF_UNCHECKED);
  171.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CW, MF_BYCOMMAND | MF_UNCHECKED);
  172.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CCW, MF_BYCOMMAND | MF_UNCHECKED);
  173.     CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_ANTIALIAS, (bAntialias ? MF_CHECKED : MF_UNCHECKED));
  174.  
  175.     switch(dCull)
  176.     {
  177.         case D3DCULL_NONE:
  178.             CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_NONE, MF_BYCOMMAND | MF_CHECKED);
  179.             break;
  180.  
  181.         case D3DCULL_CW:
  182.             CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CW, MF_BYCOMMAND | MF_CHECKED);
  183.             break;
  184.  
  185.         case D3DCULL_CCW:
  186.             CheckMenuItem(hMenu, ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CCW, MF_BYCOMMAND | MF_CHECKED);
  187.             break;
  188.     }
  189.  
  190.     switch(cTool)
  191.     {
  192.         case XDC_TOOL_NONE:
  193.             CheckMenuItem(hMenu, ID_OUTILS_AUCUN, MF_BYCOMMAND | MF_CHECKED);
  194.             break;
  195.  
  196.         case XDC_TOOL_SELECT:
  197.             CheckMenuItem(hMenu, ID_OUTILS_SLECTEUR, MF_BYCOMMAND | MF_CHECKED);
  198.             break;
  199.  
  200.         case XDC_TOOL_UNSELECT:
  201.             CheckMenuItem(hMenu, ID_OUTILS_DSLECTEUR, MF_BYCOMMAND | MF_CHECKED);
  202.             break;
  203.  
  204.         case XDC_TOOL_MAGNET:
  205.             CheckMenuItem(hMenu, ID_OUTILS_AIMANT, MF_BYCOMMAND | MF_CHECKED);
  206.             break;
  207.  
  208.         case XDC_TOOL_CURVE:
  209.             CheckMenuItem(hMenu, ID_OUTILS_COURBE, MF_BYCOMMAND | MF_CHECKED);
  210.             break;
  211.  
  212.         case XDC_TOOL_EXTRUDE:
  213.             CheckMenuItem(hMenu, ID_OUTILS_EXTRUDEUR, MF_BYCOMMAND | MF_CHECKED);
  214.             break;
  215.  
  216.         case XDC_TOOL_EDGE:
  217.             CheckMenuItem(hMenu, ID_OUTILS_ARTES, MF_BYCOMMAND | MF_CHECKED);
  218.             break;
  219.  
  220.         case XDC_TOOL_GRAB:
  221.             CheckMenuItem(hMenu, ID_OUTILS_PINCE, MF_BYCOMMAND | MF_CHECKED);
  222.             break;
  223.     }
  224. }
  225.  
  226. // Gérer les messages de la fenêtre menu / trace
  227. LRESULT CALLBACK lrMenuWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  228. {
  229.     static int iCurveStartVertex, iCurveLastVertex;
  230.     int wmId, wmEvent, iCnt, jCnt;
  231.     float fDist;
  232.     SMALLBOOL bShouldRedraw, bSelectState;
  233.     char cKey;
  234.     DWORD dwTime;
  235.     D3DCOLORVALUE    dcvDiffuse    = {1.f, 1.f, 1.f, 0.f},
  236.                     dcvSpecular    = {1.f, 1.f, 1.f, 0.f},
  237.                     dcvAmbient    = {1.f, 1.f, 1.f, 0.f};
  238.  
  239.     switch( uMsg )
  240.     {
  241.  
  242.     case WM_CREATE :
  243.         // Mettre à jour les toggle flags des menus en fonction de l'état des variables de mode
  244.         vUpdateMenu();
  245.         break;
  246.  
  247.     case WM_COMMAND :
  248.          wmId    = LOWORD(wParam);
  249.          wmEvent = HIWORD(wParam);
  250.  
  251.          switch (wmId) {
  252.  
  253.             //////////////////////////////////// M E N U  P R O J E T ///////////////
  254.             case ID_PROJET_CHARGER_SCNESCULPT :
  255.                 // Charger la scène
  256.                 vLoadSculpt();
  257.  
  258.                 // Mettre à jour les variables d'état du pipe D3D et tout redessiner
  259.                 vSetD3DState();
  260.                 goto _RedrawAll;
  261.  
  262.             case ID_PROJET_CHARGER_SCNESKULPTD3DW3D :
  263.                 // Charger la scène
  264.                 vLoadBin();
  265.  
  266.                 // Mettre à jour les variables d'état du pipe D3D et tout redessiner
  267.                 vSetD3DState();
  268.                 goto _RedrawAll;
  269.  
  270.             case ID_PROJET_CHARGER_SCNEDIRECTX :
  271.                 // Charger la scène
  272.                 vLoadDirectX();
  273.  
  274.                 // Mettre à jour les variables d'état du pipe D3D et tout redessiner
  275.                 vSetD3DState();
  276.                 goto _RedrawAll;
  277.  
  278.             case ID_PROJET_SAUVER_SCNESCULPT :
  279.                 // Sauver la scène
  280.                 vSaveSculpt();
  281.                 break;
  282.  
  283.             case ID_PROJET_SAUVER_SCNESKULPTD3DW3D :
  284.                 // Sauver la scène
  285.                 vSaveBin();
  286.                 break;
  287.  
  288.             case ID_PROJET_SAUVER_SCNEDIRECTX :
  289.                 // Sauver la scène
  290.                 vSaveDirectX();
  291.                 break;
  292.  
  293.             case ID_PROJET_APROPOS:
  294.                 vLogo();
  295.                 break;
  296.  
  297.             case ID_PROJET_RSUM :
  298.                 vDescribe();
  299.                 break;
  300.  
  301.             case ID_PROJET_QUITTER:
  302.                DestroyWindow (hWnd);
  303.                break;
  304.  
  305.             //////////////////////////////////// M E N U  E D I T I O N ///////////////
  306.             case ID_EDITION_SLECTIONNER_TOUT:
  307.             case ID_EDITION_DSLECTIONNER_TOUT:
  308.                 // (Dé)Sélectionner les sommets
  309.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  310.                 {
  311.                     if (Vertices[iCnt].bEnabled == FALSE) continue;
  312.                     if (Vertices[iCnt].bHidden == TRUE) continue;
  313.  
  314.                     Vertices[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUT ? TRUE : FALSE);
  315.                 }
  316.  
  317.                 // (Dé)Sélectionner les objets D3D
  318.                 for (iCnt = 0 ; iCnt <= iObjtLastUsed ; iCnt++)
  319.                 {
  320.                     if (Objects[iCnt].bEnabled == FALSE) continue;
  321.                     if (Objects[iCnt].bHidden == TRUE) continue;
  322.  
  323.                     Objects[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUT ? TRUE : FALSE);
  324.                 }
  325.  
  326.                 // Ne pas sélectionner les lampes
  327.                 if (wmId == ID_EDITION_SLECTIONNER_TOUT) goto _SelectDone;
  328.  
  329.                 // Désélectionner les lampes
  330.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  331.                 {
  332.                     if (Lampes[iCnt].bEnabled == FALSE) continue;
  333.  
  334.                     Lampes[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUT ? TRUE : FALSE);
  335.                 }
  336. _SelectDone:
  337.                 vForce2DRefresh(XDC_MODE_COMPLET);
  338.                 break;
  339.  
  340.             case ID_EDITION_SLECTIONNER_NOEUDSCONNEXES:
  341.                 vCollect();
  342.                 dwTime = GetTickCount();
  343.                 vPropagateSelection();
  344.                 vForce2DRefresh(XDC_MODE_COMPLET);
  345.                 vTrace("Temps propagation : %d ms", GetTickCount() - dwTime);
  346.                 break;
  347.  
  348.             case ID_EDITION_SLECTIONNER_NOEUDINDIQU:
  349.             case ID_EDITION_DSLECTIONNER_NOEUDINDIQU:
  350.                 // Attention : en mode menu, ce traitement sélectionne le noeud indiqué.
  351.                 // Il peut aussi être appelé par 2nwndproc.c en mode dé/sélecteur, avec lParam != 0.
  352.                 // Il faut alors dé/sélectionner tous les points dans la zone de tolérance et pas seulement le
  353.                 // premier
  354.  
  355.                 // Chercher le premier point dans la zone curseur
  356.                 iCnt = iFindVertex(Cursor1, -1);
  357.                 bShouldRedraw = FALSE; // Si true à l'issue du traitement alors il faut redessiner la 2D car des points ont changé d'état de sélection
  358.  
  359.                 // Si on n'a pas trouvé alors on cherche une lampe
  360.                 if (iCnt == -1)
  361.                 {
  362.                     PostMessage(hWnd, WM_COMMAND, ID_EDITION_SLECTIONNER_LAMPEINDIQUE, lParam);
  363.                     break;
  364.                 }
  365.  
  366.                 switch(lParam)
  367.                 {
  368.                 case 0: bSelectState = (wmId == ID_EDITION_SLECTIONNER_NOEUDINDIQU ? TRUE : FALSE); break;
  369.                 case XDC_SINGLETOGGLE: bSelectState = !Vertices[iCnt].bSelected; break;
  370.                 case XDC_SELECTALL: bSelectState = TRUE; break;
  371.                 case XDC_DESELECTALL: bSelectState = FALSE; break;
  372.                 }
  373.  
  374.                 while (iCnt != -1)
  375.                 {
  376.                     if (Vertices[iCnt].bSelected != bSelectState)
  377.                     {
  378.                         Vertices[iCnt].bSelected = bSelectState;
  379.                         PostMessage(hWndTop, WM_USER+1, iCnt, 0);
  380.                         PostMessage(hWndFace, WM_USER+1, iCnt, 0);
  381.                         PostMessage(hWndRight, WM_USER+1, iCnt, 0);
  382.                         bShouldRedraw = TRUE;
  383.                     }
  384.  
  385.                     // Trouver le point suivant si on est en mode outil sélecteur (lParam == XDC_SELECTALL)
  386.                     if ((lParam == XDC_SELECTALL) || (lParam == XDC_DESELECTALL))
  387.                         iCnt = iFindVertex(Cursor1, iCnt);
  388.                     else
  389.                         iCnt = -1;
  390.                 }
  391.  
  392.                 // Redessiner partiellement les vues 2D si des points ont été traités
  393.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_PARTIEL);
  394.                 break;
  395.  
  396.             case ID_EDITION_SLECTIONNER_LAMPEINDIQUE:
  397.             case ID_EDITION_DSLECTIONNER_LAMPEINDIQUE:
  398.                 // Chercher la lampe dans la zone curseur
  399.                 iCnt = iFindLamp(Cursor1, -1);
  400.                 bShouldRedraw = FALSE; // Si true à l'issue du traitement alors il faut redessiner la 2D car des points ont changé d'état de sélection
  401.  
  402.                 // Si on n'a pas trouvé alors on cherche un objet D3D
  403.                 if (iCnt == -1)
  404.                 {
  405.                     PostMessage(hWnd, WM_COMMAND, ID_EDITION_SLECTIONNER_OBJETD3DINDIQU, lParam);
  406.                     break;
  407.                 }
  408.  
  409.                 switch(lParam)
  410.                 {
  411.                 case 0: bSelectState = (wmId == ID_EDITION_SLECTIONNER_LAMPEINDIQUE ? TRUE : FALSE); break;
  412.                 case XDC_SINGLETOGGLE: bSelectState = !Lampes[iCnt].bSelected; break;
  413.                 case XDC_SELECTALL: bSelectState = TRUE; break;
  414.                 case XDC_DESELECTALL: bSelectState = FALSE; break;
  415.                 }
  416.  
  417.                 while (iCnt != -1)
  418.                 {
  419.                     if (Lampes[iCnt].bSelected != bSelectState)
  420.                     {
  421.                         Lampes[iCnt].bSelected = bSelectState;
  422.                         bShouldRedraw = TRUE;
  423.                     }
  424.                     if ((lParam == XDC_SELECTALL) || (lParam == XDC_DESELECTALL))
  425.                         iCnt = iFindLamp(Cursor1, iCnt);
  426.                     else
  427.                         iCnt = -1;
  428.                 }
  429.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_COMPLET);
  430.                 break;
  431.  
  432.             case ID_EDITION_SLECTIONNER_TOUTESLESLAMPES:
  433.             case ID_EDITION_DSLECTIONNER_TOUTESLESLAMPES:
  434.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  435.                     if (Lampes[iCnt].bEnabled)
  436.                         Lampes[iCnt].bSelected = (wmId == ID_EDITION_SLECTIONNER_TOUTESLESLAMPES ? TRUE : FALSE);
  437.                 vForce2DRefresh(XDC_MODE_COMPLET);
  438.                 break;
  439.  
  440.             case ID_EDITION_SLECTIONNER_OBJETD3DINDIQU:
  441.             case ID_EDITION_DSLECTIONNER_OBJETD3DINDIQU:
  442.                 // Chercher le premier point dans la zone curseur
  443.                 iCnt = iFindD3DObject(Cursor1, -1);
  444.                 bShouldRedraw = FALSE; // Si true à l'issue du traitement alors il faut redessiner la 2D car des points ont changé d'état de sélection
  445.  
  446.                 if (iCnt == -1) break;
  447.  
  448.                 switch(lParam)
  449.                 {
  450.                 case 0: bSelectState = (wmId == ID_EDITION_SLECTIONNER_OBJETD3DINDIQU ? TRUE : FALSE); break;
  451.                 case XDC_SINGLETOGGLE: bSelectState = !Objects[iCnt].bSelected; break;
  452.                 case XDC_SELECTALL: bSelectState = TRUE; break;
  453.                 case XDC_DESELECTALL: bSelectState = FALSE; break;
  454.                 }
  455.  
  456.                 while (iCnt != -1)
  457.                 {
  458.                     if (Objects[iCnt].bSelected != bSelectState)
  459.                     {
  460.                         Objects[iCnt].bSelected = bSelectState;
  461.                         bShouldRedraw = TRUE;
  462.                     }
  463.                     if ((lParam == XDC_SELECTALL) || (lParam == XDC_DESELECTALL))
  464.                         iCnt = iFindD3DObject(Cursor1, iCnt);
  465.                     else
  466.                         iCnt = -1;
  467.                 }
  468.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_COMPLET);
  469.                 break;
  470.  
  471.             case ID_EDITION_SLECTIONNER_INVERSERLASLECTION:
  472.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  473.                     if (Vertices[iCnt].bEnabled)
  474.                         Vertices[iCnt].bSelected = (Vertices[iCnt].bSelected ? FALSE : TRUE);
  475.                 for (iCnt = 0 ; iCnt <= iObjtLastUsed ; iCnt++)
  476.                     if (Objects[iCnt].bEnabled)
  477.                         Objects[iCnt].bSelected = (Objects[iCnt].bSelected ? FALSE : TRUE);
  478.                 vForce2DRefresh(XDC_MODE_COMPLET);
  479.                 break;
  480.  
  481.             case ID_EDITION_EFFACER_TOUT :
  482.                 vDeleteObjects();
  483.                 goto _RedrawAll;
  484.  
  485.             case ID_EDITION_EFFACER_NOEUDINDIQU:
  486.                 iCnt = iFindVertex(Cursor1, -1);
  487.                 if (iCnt != -1)
  488.                 {
  489.                     if (bDeleteVertex(iCnt))
  490.                         goto _RedrawAll;
  491.                 }
  492.                 else
  493.                     vTrace("*** E0010 : Pas de noeud à proximité du curseur principal");
  494.                 break;
  495.  
  496.             case ID_EDITION_EFFACER_NOAUDSSLECTIONNS:
  497.                 bShouldRedraw = FALSE;
  498.  
  499.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  500.                     if (bIsVertexSelected(iCnt))
  501.                         bShouldRedraw |= bDeleteVertex(iCnt);
  502.                 
  503.                 if (bShouldRedraw)
  504.                     goto _RedrawAll;
  505.                 break;
  506.  
  507.             case ID_EDITION_EFFACER_ARTESSLECTIONNES:
  508.                 bShouldRedraw = FALSE;
  509.                 for (iCnt = 0 ; iCnt <= iEdgeLastUsed ; iCnt++)
  510.                 {
  511.                     if (Edges[iCnt].bEnabled == FALSE) continue;
  512.  
  513.                     if (
  514.                             (Vertices[Edges[iCnt].iSommets[0]].bSelected)
  515.                          && (Vertices[Edges[iCnt].iSommets[1]].bSelected)
  516.                        )
  517.                     {
  518.                        bDeleteEdge(iCnt);
  519.                        bShouldRedraw = TRUE;
  520.                     }
  521.                 }
  522.  
  523.                 if (bShouldRedraw) vForce2DRefresh(XDC_MODE_COMPLET);
  524.                 break;
  525.  
  526.             case ID_EDITION_EFFACER_TRIANGLESSLECTIONNS:
  527.                 bShouldRedraw = FALSE;
  528.                 for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
  529.                 {
  530.                     if (Triangles[iCnt].bEnabled == FALSE) continue;
  531.  
  532.                     if (bIsTriangleSelected(iCnt))
  533.                     {
  534.                        bDeleteTriangle(iCnt);
  535.                        bShouldRedraw = TRUE;
  536.                     }
  537.                 }
  538.  
  539.                 if (bShouldRedraw) goto _RedrawAll;
  540.                 break;
  541.  
  542.             case ID_EDITION_EFFACER_LAMPEINDIQUE:
  543.                 iCnt = iFindLamp(Cursor1, -1);
  544.                 if (iCnt != -1)
  545.                 {
  546.                     if (bDeleteLamp(iCnt))
  547.                         goto _RedrawAll;
  548.                 }
  549.                 else
  550.                     vTrace("*** E0011 : Pas de lampe à proximité du curseur principal");
  551.                 break;
  552.  
  553.             case ID_EDITION_EFFACER_LAMPESSLECTIONNES:
  554.                 bShouldRedraw = FALSE;
  555.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  556.                 {
  557.                     if (Lampes[iCnt].bEnabled == FALSE) continue;
  558.  
  559.                     if (Lampes[iCnt].bSelected)
  560.                     {
  561.                         bDeleteLamp(iCnt);
  562.                         bShouldRedraw = TRUE;
  563.                     }
  564.                 }
  565.  
  566.                 if (bShouldRedraw) goto _RedrawAll;
  567.                 break;
  568.  
  569.             case ID_EDITION_EFFACER_TOUTESLESLAMPES:
  570.                 bShouldRedraw = FALSE;
  571.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  572.                 {
  573.                     if (Lampes[iCnt].bEnabled == FALSE) continue;
  574.                     bDeleteLamp(iCnt);
  575.                     bShouldRedraw = TRUE;
  576.                 }
  577.  
  578.                 if (bShouldRedraw) goto _RedrawAll;
  579.                 break;
  580.  
  581.             case ID_EDITION_MODIFIER_FACETTES :
  582.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_FACE), hWnd, bFaceDlgProc);
  583.                 break;
  584.  
  585.             case ID_EDITION_TRANSFORMER_AGRANDIRRDUIRE:
  586.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_EXPAND), hWnd, bExpandDlgProc);
  587.                 break;
  588.  
  589.             case ID_EDITION_TRANSFORMER_REMPLIR:
  590.                 fill();
  591.                 goto _RedrawAll;
  592.  
  593.             case ID_EDITION_TRANSFORMER_SUBDIVISER:
  594.                 {
  595.                     int iTriNum = iTriaLastUsed;
  596.                     SMALLBOOL *bSubdiv = (SMALLBOOL *) malloc((iTriNum + 1) * sizeof(SMALLBOOL));
  597.                     if (!bSubdiv) break;
  598.                     ZeroMemory(bSubdiv, (iTriNum + 1) * sizeof(SMALLBOOL));
  599.  
  600.                     for (iCnt = 0 ; iCnt <= iTriNum ; iCnt++)
  601.                     {
  602.                         if (Triangles[iCnt].bEnabled == FALSE) continue;
  603.                         bSubdiv[iCnt] = bIsTriangleSelected(iCnt);
  604.                     }
  605.  
  606.                     bShouldRedraw = FALSE;
  607.                     for (iCnt = 0 ; iCnt <= iTriNum ; iCnt++)
  608.                         if (bSubdiv[iCnt])
  609.                         {
  610.                             bSubdivideTriangle(iCnt);
  611.                             bShouldRedraw = TRUE;
  612.                         }
  613.  
  614.                     free(bSubdiv);
  615.  
  616.                     if (bShouldRedraw) goto _RedrawAll;
  617.                 }
  618.                 break;
  619.  
  620.             case ID_EDITION_TRANSFORMER_RPLIQUERSURHLICE:
  621.                 iCnt = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELIX), hWnd, bHelixDlgProc, (LPARAM) 20 << 16 | 20);
  622.                 break;
  623.  
  624.             case ID_EDITION_TRANSFORMER_LISSERLESNOEUDSSLECTIONNS:
  625.             case ID_EDITION_TRANSFORMER_DLISSERLESNOEUDSSLECTIONNS:
  626.                 bSelectState = (wmId == ID_EDITION_TRANSFORMER_LISSERLESNOEUDSSLECTIONNS);
  627.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  628.                 {
  629.                     if (Vertices[iCnt].bEnabled == FALSE) continue;
  630.                     if (Vertices[iCnt].bSelected == FALSE) continue;
  631.                     if (Vertices[iCnt].bSmooth == bSelectState) continue;
  632.  
  633.                     Vertices[iCnt].bSmooth = bSelectState;
  634.                 }
  635.                 for (iCnt = 0 ; iCnt <= iTriaLastUsed ; iCnt++)
  636.                     if (
  637.                             (Vertices[Triangles[iCnt].iSommets[0]].bSelected)
  638.                          || (Vertices[Triangles[iCnt].iSommets[1]].bSelected)
  639.                          || (Vertices[Triangles[iCnt].iSommets[2]].bSelected)
  640.                        )
  641.                         bUpdateD3DTri(iCnt);
  642.                 goto _RedrawAll;
  643.             
  644.             case ID_EDITION_TRANSFORMER_CACHERLESNOEUDSSLECTIONNS:
  645.                 vHideSelection();
  646.                 goto _RedrawAll;
  647.  
  648.             case ID_EDITION_TRANSFORMER_RVLERLESNOEUDSCACHS:
  649.                 vRevealHidden();
  650. _RedrawAll:
  651.                 // Tout retracer
  652.                 vForce2DRefresh(XDC_MODE_COMPLET);
  653.                 vForce3DRefresh(XDC_MODE_COMPLET);
  654.                 break;
  655.  
  656.             case ID_EDITION_TRANSFORMER_MULTIVIEW:
  657.                 vRemakeTriview(NULL);
  658.                 break;
  659.  
  660.             case ID_EDITION_AJOUTER_UNCLNE:
  661.                 cTool = XDC_TOOL_GRAB;
  662.                 bCloneSelection(D3DVECTOR(0.f, 0.f, 0.f), XDC_MODE_CLONE);
  663.                 vUpdateMenu();
  664.                 vForce2DRefresh(XDC_MODE_COMPLET);
  665.                 break;
  666.             
  667.             case ID_EDITION_AJOUTER_POINT:
  668.                 iCnt = iMakeVertex(Cursor1, XDC_ALLOWSAME);
  669.                 if (cTool == XDC_TOOL_CURVE)
  670.                 {
  671.                     // Si le vertex n'est pas le premier de la courbe, tracer l'arête et redessiner en mode complet
  672.                     if (iCurveLastVertex != -1)
  673.                     {
  674.                         iMakeEdge(iCurveLastVertex, iCnt);
  675.                         vForce2DRefresh(XDC_MODE_COMPLET);
  676.                     }
  677.                     else // Sinon redessiner en mode partiel après avoir forcé le dessin du point, et mémoriser l'indice du point pour pouvoir refermer la courbe sur 'f'
  678.                     {
  679.                         iCurveStartVertex = iCnt;
  680.                         PostMessage(hWndTop, WM_USER+1, iCnt, 0);
  681.                         PostMessage(hWndFace, WM_USER+1, iCnt, 0);
  682.                         PostMessage(hWndRight, WM_USER+1, iCnt, 0);
  683.                         vForce2DRefresh(XDC_MODE_PARTIEL);
  684.                     }
  685.  
  686.                     iCurveLastVertex = iCnt;
  687.                 }
  688.                 else
  689.                 {
  690.                     // Forcer le dessin du point et rafraichir 2D en mode partiel
  691.                     PostMessage(hWndTop, WM_USER+1, iCnt, 0);
  692.                     PostMessage(hWndFace, WM_USER+1, iCnt, 0);
  693.                     PostMessage(hWndRight, WM_USER+1, iCnt, 0);
  694.                     vForce2DRefresh(XDC_MODE_PARTIEL);
  695.                 }
  696.                 break;
  697.  
  698.             case ID_EDITION_AJOUTER_ARTEOUTRIANGLE:
  699.                 break;
  700.  
  701.             case ID_EDITION_AJOUTER_SPHRE:
  702.             case ID_EDITION_AJOUTER_HMISPHRE:
  703.                 iCnt = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SPHERE), hWnd, bSphereDlgProc, (LPARAM) 20 << 16 | 20);
  704.                 if (iCnt == -1) break;
  705.                 
  706.                 // Récupérer le nombre de subdivisions horizontales & verticales
  707.                 // dans le hiword et le loword du code de retour
  708.                 jCnt = HIWORD(iCnt);
  709.                 iCnt = LOWORD(iCnt);
  710.  
  711.                 // Ajouter la sphère
  712.                 vAddSphere(Cursor1, 6.f, iCnt, jCnt, (wmId == ID_EDITION_AJOUTER_HMISPHRE));
  713.                 goto _RedrawAll;
  714.  
  715.             case ID_EDITION_AJOUTER_TORE:
  716.                 iCnt = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SPHERE), hWnd, bSphereDlgProc, (LPARAM) 20 << 16 | 20);
  717.                 if (iCnt == -1) break;
  718.                 
  719.                 // Récupérer le nombre de subdivisions horizontales & verticales
  720.                 // dans le hiword et le loword du code de retour
  721.                 jCnt = HIWORD(iCnt);
  722.                 iCnt = LOWORD(iCnt);
  723.  
  724.                 // Ajouter le tore
  725.                 vAddTorus(Cursor1, 7., 6., iCnt, jCnt);
  726.                 goto _RedrawAll;
  727.  
  728.             case ID_EDITION_AJOUTER_BOINGBALL:
  729.                 // Ajouter la boing ball
  730.                 vAddBoing(Cursor1, 6.f);
  731.                 goto _RedrawAll;
  732.  
  733.             case ID_EDITION_AJOUTER_DISQUE:
  734.                 iCnt = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBDIV), hWnd, bSphereDlgProc, (LPARAM) 20 << 16 | 20);
  735.                 if (iCnt == -1) break;
  736.  
  737.                 // Ajouter le cercle
  738.                 vAddDisk(Cursor1, 6., LOWORD(iCnt));
  739.                 goto _RedrawAll;
  740.  
  741.             case ID_EDITION_AJOUTER_CERCLE:
  742.                 iCnt = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBDIV), hWnd, bSphereDlgProc, (LPARAM) 20 << 16 | 20);
  743.                 if (iCnt == -1) break;
  744.  
  745.                 // Ajouter le cercle
  746.                 vAddCircle(Cursor1, 6., LOWORD(iCnt));
  747.                 vForce2DRefresh(XDC_MODE_COMPLET);
  748.                 break;
  749.  
  750.             case ID_EDITION_AJOUTER_LAMPE:
  751.                 iMakeLamp(
  752.                         D3DLIGHT_POINT,
  753.                         dcvDiffuse,
  754.                         dcvSpecular,
  755.                         dcvAmbient,
  756.                         Cursor1,
  757.                         D3DVECTOR(0.f, 0.f, 0.f),
  758.                         D3DLIGHT_RANGE_MAX,
  759.                         0.f,
  760.                         0.f,
  761.                         0.1f,
  762.                         0.f,
  763.                         0.f,
  764.                         0.f);
  765.                 goto _RedrawAll;
  766. #ifndef NO3D
  767.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_CUBE:
  768.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  769.                 D3DXCreateBox(lpd3dDevice,  5.f, 5.F, 5.f, D3DX_DEFAULT, &Objects[iCnt].pShape);
  770.                 bMoveD3DObj(iCnt, Cursor1);
  771.                 goto _RedrawAll;
  772.  
  773.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_CYLINDRE:
  774.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  775.                 D3DXCreateCylinder(lpd3dDevice,  3.f, 3.f, 7.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  776.                 bMoveD3DObj(iCnt, Cursor1);
  777.                 goto _RedrawAll;
  778.  
  779.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_CNE:
  780.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  781.                 D3DXCreateCylinder(lpd3dDevice,  0.f, 4.f, 7.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  782.                 bMoveD3DObj(iCnt, Cursor1);
  783.                 goto _RedrawAll;
  784.  
  785.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_DONUT:
  786.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  787.                 D3DXCreateTorus(lpd3dDevice,  3.f, 7.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  788.                 bMoveD3DObj(iCnt, Cursor1);
  789.                 goto _RedrawAll;
  790.  
  791.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_POLYGONE:
  792.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  793.                 D3DXCreatePolygon(lpd3dDevice,  1.f, 20, D3DX_DEFAULT, &Objects[iCnt].pShape);
  794.                 bMoveD3DObj(iCnt, Cursor1);
  795.                 goto _RedrawAll;
  796.  
  797.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_SPHRE:
  798.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  799.                 D3DXCreateSphere(lpd3dDevice,  6.f, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &Objects[iCnt].pShape);
  800.                 bMoveD3DObj(iCnt, Cursor1);
  801.                 goto _RedrawAll;
  802.  
  803.             case ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_TEAPOT:
  804.                 if (-1 == (iCnt = iMakeD3DObj())) break;
  805.                 D3DXCreateTeapot(lpd3dDevice,  D3DX_DEFAULT, &Objects[iCnt].pShape);
  806.                 bMoveD3DObj(iCnt, Cursor1);
  807.                 if (lParam) // Patch pour ne pas tout redessiner si on est en Timedemo
  808.                     break;
  809.                 goto _RedrawAll;
  810. #endif
  811.  
  812.             case ID_EDITION_AJOUTER_CHANEDECARACTRES:
  813.                 vAddTextOutline();
  814.                 goto _RedrawAll;
  815.  
  816.             case ID_EDITION_COLLER_CURSEURSURNOEUD:
  817.                 jCnt = -1;
  818.                 fDist = 1.0e10f;
  819.  
  820.                 for (iCnt = 0 ; iCnt <= iVertLastUsed ; iCnt++)
  821.                     if ((Vertices[iCnt].bEnabled) && (fDist > SquareMagnitude(Cursor1 - Vertices[iCnt].vPoint)))
  822.                     {
  823.                         jCnt = iCnt;
  824.                         fDist = SquareMagnitude(Cursor1 - Vertices[iCnt].vPoint);
  825.                     }
  826.  
  827.                 if (jCnt > -1)
  828.                 {
  829.                     Cursor1 = Vertices[jCnt].vPoint;
  830.                     vForce2DRefresh(XDC_MODE_PARTIEL);
  831.                 }
  832.                 else
  833.                     vTrace("*** E0012 : Aucun noeud");
  834.                 break;
  835.  
  836.             case ID_EDITION_COLLER_CURSEURSURCENTRE:
  837.                 Cursor1 = vCenter();
  838.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  839.                 break;
  840.  
  841.             case ID_EDITION_GRILLE :
  842.                 bGrid = bGrid ? FALSE : TRUE;
  843.                 vUpdateMenu();
  844.                 vForce2DRefresh(XDC_MODE_COMPLET);
  845.                 break;
  846.  
  847.             case ID_EDITION_GRIDSTEP :
  848.                 iCnt = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GRIDSTEP), hWnd, bSphereDlgProc, (LPARAM) (int) (100.f * fGridSize) << 16);
  849.                 if (iCnt == -1) break;
  850.  
  851.                 // Régler pas grille
  852.                 fGridSize = LOWORD(iCnt) / 100.f;
  853.                 vForce2DRefresh(XDC_MODE_COMPLET);
  854.                 break;
  855.  
  856.             case ID_EDITION_COORDONNES :
  857.                 bCoords = bCoords ? FALSE : TRUE;
  858.                 vUpdateMenu();
  859.                 vForce2DRefresh(XDC_MODE_COMPLET);
  860.                 break;
  861.  
  862.             //////////////////////////////////// M E N U  O U T I L ///////////////////////////
  863.             case ID_OUTILS_AUCUN:
  864.                 cTool = XDC_TOOL_NONE;
  865.                 goto _ToolDone;
  866.  
  867.             case ID_OUTILS_SLECTEUR:
  868.                 cTool = XDC_TOOL_SELECT;
  869.                 goto _ToolDone;
  870.  
  871.             case ID_OUTILS_DSLECTEUR:
  872.                 cTool = XDC_TOOL_UNSELECT;
  873.                 goto _ToolDone;
  874.  
  875.             case ID_OUTILS_AIMANT:
  876.                 cTool = XDC_TOOL_MAGNET;
  877.                 goto _ToolDone;
  878.  
  879.             case ID_OUTILS_COURBE:
  880.                 cTool = XDC_TOOL_CURVE;
  881.                 iCurveLastVertex = -1;
  882.                 goto _ToolDone;
  883.  
  884.             case ID_OUTILS_COURBE_FINIRF:
  885.                 if (cTool == XDC_TOOL_CURVE)
  886.                 {
  887.                     // Si la courbe a au moins 2 sommets alors la refermer
  888.                     if (iCurveLastVertex != -1 && iCurveLastVertex != iCurveStartVertex)
  889.                     {
  890.                         if (-1 == iFindEdge(iCurveLastVertex, iCurveStartVertex))
  891.                         {
  892.                             iMakeEdge(iCurveLastVertex, iCurveStartVertex);
  893.                             vForce2DRefresh(XDC_MODE_COMPLET);
  894.                             iCurveLastVertex = -1;
  895.                         }
  896.                         else
  897.                             vTrace("*** E0013 : L'arête de fermeture existe déjà");
  898.                     }
  899.                     else
  900.                         vTrace("*** E0014 : La courbe ne peut être fermée, elle n'a pas au moins 2 points");
  901.                 }
  902.                 goto _ToolDone;
  903.  
  904.             case ID_OUTILS_EXTRUDEUR:
  905.                 cTool = XDC_TOOL_GRAB;
  906.                 bCloneSelection(D3DVECTOR(0.f, 0.0f, 0.f), XDC_MODE_EXTRUDE);
  907.                 vUpdateMenu();
  908.                 vForce2DRefresh(XDC_MODE_COMPLET);
  909.                 break;
  910.  
  911.             case ID_OUTILS_ARTES:
  912.                 cTool = XDC_TOOL_EDGE;
  913.                 goto _ToolDone;
  914.  
  915.             case ID_OUTILS_PINCE:
  916.                 cTool = XDC_TOOL_GRAB;
  917. _ToolDone:
  918.                 vUpdateMenu();
  919.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  920.                 break;
  921.  
  922.             //////////////////////////////////// M E N U  O B S E R V A T E U R ///////////////
  923.             case ID_OBSERVATEUR_DFINIROBSERVATEUR:
  924.                 Observer = Cursor1;
  925.                 D3DUtil_SetViewMatrix(matView,
  926.                       Observer,    // From
  927.                       Target,    // To
  928.                       D3DVECTOR(0.f, 0.f, 0.f));
  929.  
  930.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  931.                 goto _ModeDone;
  932.  
  933.             case ID_OBSERVATEUR_DFINIRVISE:
  934.                 Target = Cursor1;
  935.                 D3DUtil_SetViewMatrix(matView,
  936.                       Observer,    // From
  937.                       Target,    // To
  938.                       D3DVECTOR(0.f, 0.f, 0.f));
  939.  
  940.                 vForce2DRefresh(XDC_MODE_PARTIEL);
  941.                 goto _ModeDone;
  942.  
  943.             case ID_OBSERVATEUR_MODE_POINT:
  944.                 dFillMode = D3DFILL_POINT;
  945.                 goto _ModeDone;
  946.  
  947.             case ID_OBSERVATEUR_MODE_FILDEFERF:
  948.                 dFillMode = D3DFILL_WIREFRAME;
  949.                 goto _ModeDone;
  950.  
  951.             case ID_OBSERVATEUR_MODE_FACETTES:
  952.                 dFillMode = D3DFILL_SOLID;
  953.                 goto _ModeDone;
  954.  
  955.             case ID_OBSERVATEUR_MODE_ZBUFFER:
  956.                 dZBuf = (dZBuf == D3DZB_TRUE) ? D3DZB_FALSE : D3DZB_TRUE;
  957.                 goto _ModeDone;
  958.  
  959.             //////////////////////////////////// M E N U  M O N D E ///////////////
  960.             case ID_MONDE_ILLUMINATIONGLOBALE :
  961.                 DialogBox(hInst, MAKEINTRESOURCE(IDD_GLOBLIGHT), hWnd, bGlobLightDlgProc);
  962.                 break;
  963.  
  964.             //////////////////////////////////// M E N U  D3D ///////////////
  965.             case ID_SPCIFICITSDX7D3DIM_CHANGERLERENDERDEVICED3D:
  966.                 if (S_OK != D3DEnum_UserChangeDevice(&m_pDeviceInfo))
  967.                     break;
  968.  
  969.                 bReady = FALSE;
  970.  
  971.                 sprintf(cTitle, "%s(%s)", XDC_S_Title3D, m_pDeviceInfo->strDesc);
  972.                 SendMessage(hWndPersp, WM_SETTEXT, 0, (LPARAM)cTitle);
  973.  
  974.                 if( FAILED( hrCloseD3D(FALSE) ) )
  975.                     DestroyWindow( hWndMenu );
  976.  
  977.                 if( FAILED( hrInitD3D( hWndPersp, m_pDeviceInfo->pDeviceGUID) ) )
  978.                     DestroyWindow( hWndMenu );
  979.  
  980.                 if (FAILED(hrInitWorld( lpd3dDevice )))
  981.                 {
  982.                     hrCloseD3D(TRUE);
  983.                     DestroyWindow( hWndMenu );
  984.                 }
  985.  
  986.                 // Mettre à jour les variables d'état du pipe D3D
  987.                 vSetD3DState();
  988.  
  989.                 // Remettre en service les lampes
  990.                 for (iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  991.                     if (Lampes[iCnt].bEnabled)
  992.                         bUpdateLamp(iCnt);
  993.  
  994.                 bReady = TRUE;
  995.  
  996.                 // Redessiner la scène
  997.                 vForce3DRefresh(XDC_MODE_COMPLET);
  998.                 break;
  999.  
  1000.             case ID_SPCIFICITSDX7D3DIM_TRANSPARENCEALPHABLENDING:
  1001.                 bAlpha = bAlpha ? FALSE : TRUE;
  1002.                 goto _ModeDone;
  1003.  
  1004.             case ID_SPCIFICITSDX7D3DIM_ECLAIRAGESPCULAIRE:
  1005.                 bSpecular = bSpecular ? FALSE : TRUE;
  1006. _ModeDone:
  1007.                 // Mettre à jour le menu pour prendre en compte le changement de mode
  1008.                 vUpdateMenu();
  1009.                 
  1010.                 // Mettre à jour les variables d'état du pipe D3D
  1011.                 vSetD3DState();
  1012.                                 
  1013.                 // Redessiner la 3D
  1014.                 vForce3DRefresh(XDC_MODE_COMPLET);
  1015.                 break;
  1016.  
  1017.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_ANTIALIAS:
  1018.                 bAntialias = bAntialias ? FALSE:TRUE;
  1019.                 goto _ModeDone;
  1020.                 
  1021.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_NONE:
  1022.                 dCull = D3DCULL_NONE;
  1023.                 goto _ModeDone;
  1024.  
  1025.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CW:
  1026.                 dCull = D3DCULL_CW;
  1027.                 goto _ModeDone;
  1028.  
  1029.             case ID_SPCIFICITSDX7D3DIM_RENDERSTATE_BACKFACECULLINGMODE_CCW:
  1030.                 dCull = D3DCULL_CCW;
  1031.                 goto _ModeDone;
  1032.  
  1033.             case ID_SPCIFICITSDX7D3DIM_TIMEDEMO:
  1034.                 // Tout effacer
  1035.                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_EFFACER_TOUT, 0);
  1036.                 
  1037.                 // Recadrer la 2D
  1038.                 fXmin = -10.;                                // Espace de travail triview : X min
  1039.                 fXmax = 10.;                                // Espace de travail triview : X max
  1040.                 fYmin = -10.;                                // Espace de travail triview : Y min
  1041.                 fYmax = 10.;                                // Espace de travail triview : Y max
  1042.                 fZmin = -10.;                                // Espace de travail triview : Z min
  1043.                 fZmax = 10.;                                // Espace de travail triview : Z max
  1044.                 
  1045.                 // Repositionner les fenêtres
  1046.                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_TRANSFORMER_MULTIVIEW, 0);
  1047.                 
  1048.                 // Initialiser les matrices view, proj, world
  1049.                 hrInitWorld(lpd3dDevice);
  1050.  
  1051.                 // Prépositionner l'observateur et le target
  1052.                 Target = D3DVECTOR(0.f, 0.f, 0.f);
  1053.                 Observer = D3DVECTOR(7.f, 7.f, 7.f);
  1054.  
  1055.                 // Recalculer les matrices
  1056.                 D3DUtil_SetViewMatrix(matView,
  1057.                           Observer,    // From
  1058.                           Target,    // To
  1059.                           D3DVECTOR(0.f, 0.f, 0.f));
  1060.  
  1061.                 // Actualiser les matrices D3D
  1062.                 vSetD3DState();
  1063.  
  1064.                 // Ajouter 3 x 3 x 3 théière
  1065.                 {
  1066.                     int iX, iY, iZ;
  1067.                     for (iX = -3 ; iX < 4 ; iX += 3)
  1068.                         for (iY = -3 ; iY < 4 ; iY += 3)
  1069.                             for (iZ = -3 ; iZ < 4 ; iZ+= 3)
  1070.                             {
  1071.                                 Cursor1 = D3DVECTOR((float) iX, (float) iY, (float) iZ);
  1072.                                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_PRIMITIVESIMPLESHAPED3D_TEAPOT, 1);
  1073.                             }
  1074.                 }
  1075.                 
  1076.                 // Ajouter une lampe
  1077.                 Cursor1 = D3DVECTOR(8.f, 8.f, 8.f);
  1078.                 SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_LAMPE, 0);
  1079.                 
  1080.                 dwTime = GetTickCount();
  1081.                 for (iCnt = 0 ; iCnt < 90 ; iCnt++)
  1082.                 {
  1083.                     // Repositionner l'observer
  1084.                     Observer = D3DVECTOR(    7.f * sinf(g_2_PI * (float) iCnt / 360.f),
  1085.                                             7.f * cosf(g_2_PI * (float) iCnt / 360.f),
  1086.                                             7.f * sinf(g_2_PI * (float) iCnt / 360.f));
  1087.  
  1088.                     // Recalculer les matrices
  1089.                     D3DUtil_SetViewMatrix(matView,
  1090.                               Observer,    // From
  1091.                               Target,    // To
  1092.                               D3DVECTOR(0.f, 0.f, 0.f));
  1093.  
  1094.                     // Actualiser les matrices D3D
  1095.                     vSetD3DState();
  1096.  
  1097.                     // Retracer la 3D
  1098.                     vForce3DRefresh(XDC_MODE_COMPLET);
  1099.                 }
  1100.                 dwTime = GetTickCount() - dwTime;
  1101.                 
  1102.                 // Tout effacer
  1103.                 // SendMessage(hWndMenu, WM_COMMAND, ID_EDITION_EFFACER_TOUT, 0);
  1104.  
  1105.                 vTrace("Timedemo exécutée en %d ms", dwTime);
  1106.                 break;
  1107.  
  1108.             default:
  1109.                 vTrace("*** E0015 : Entrée menu non traitée dans cette version");
  1110.                return (DefWindowProc(hWnd, uMsg, wParam, lParam));
  1111.          }
  1112.         break;
  1113.         
  1114.     case WM_MOVE:
  1115.         break;
  1116.  
  1117.     case WM_SIZE:
  1118.         RECT rect;
  1119.  
  1120.         GetClientRect(hWndMenu, &rect);
  1121.         rect.left, rect.top, rect.right, rect.bottom,
  1122.         MoveWindow(hWndTrace, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); 
  1123.         break;
  1124.  
  1125.     case WM_GETMINMAXINFO:
  1126.         // Prevent the window from going smaller than some minimum size
  1127.         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
  1128.         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
  1129.         break;
  1130.  
  1131.     case WM_CHAR:
  1132.             // Touches clavier :
  1133.             // 'o' : observer <- curseur 1
  1134.             // 't' : target <- curseur 1
  1135.             cKey = (TCHAR) wParam;    // character code 
  1136.             switch(tolower(cKey))
  1137.             {
  1138. #ifdef _DEBUG
  1139.             case 'z' : // Insérer un marqueur de trace
  1140.                 vTrace("********");
  1141.                 break;
  1142. #endif
  1143.             case 'o' :    // Positionner observateur
  1144.                 PostMessage(hWndMenu, WM_COMMAND, ID_OBSERVATEUR_DFINIROBSERVATEUR, 0);
  1145.                 break;
  1146.  
  1147.             case 't' :    // Positionner cible
  1148.                 PostMessage(hWndMenu, WM_COMMAND, ID_OBSERVATEUR_DFINIRVISE, 0);
  1149.                 break;
  1150.  
  1151.             case 'p' : // Ajouter point
  1152.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_AJOUTER_POINT, 0);
  1153.                 break;
  1154.  
  1155.             case ' ' : // Aucun outil
  1156.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_AUCUN, 0);
  1157.                 break;
  1158.  
  1159.             case 'c' : // Outil Courbes
  1160.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_COURBE, 0);
  1161.                 break;
  1162.  
  1163.             case 'f' : // Outil finir courbe
  1164.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_COURBE_FINIRF, 0);
  1165.                 break;
  1166.  
  1167.             case 's' : // Outil Sélecteur
  1168.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_SLECTEUR, 0);
  1169.                 break;
  1170.  
  1171.             case 'u' : // Outil Désélecteur
  1172.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_DSLECTEUR, 0);
  1173.                 break;
  1174.  
  1175.             case 'x' : // Outil Extrudeur
  1176.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_EXTRUDEUR, 0);
  1177.                 break;
  1178.  
  1179.             case 'g' : // Outil Grabber
  1180.                 PostMessage(hWndMenu, WM_COMMAND, ID_OUTILS_PINCE, 0);
  1181.                 break;
  1182.  
  1183.             case 'k' : // Sélectionner les noeuds connexes
  1184.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_SLECTIONNER_NOEUDSCONNEXES, 0);
  1185.                 break;
  1186.  
  1187.             case 'i' : // Inverser la sélection
  1188.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_SLECTIONNER_INVERSERLASLECTION, 0);
  1189.                 break;
  1190.  
  1191.             case '<' : // Désélectionner tout
  1192.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_DSLECTIONNER_TOUT, 0);
  1193.                 break;
  1194.  
  1195.             case '>' : // Sélectionner tout
  1196.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_SLECTIONNER_TOUT, 0);
  1197.                 break;
  1198.  
  1199.             case 27 :    // Resizer le triview
  1200.                 PostMessage(hWndMenu, WM_COMMAND, ID_EDITION_TRANSFORMER_MULTIVIEW, 0);
  1201.                 break;
  1202.  
  1203.             case 'r' :    // Choisir le device de render
  1204.                 PostMessage(hWndMenu, WM_COMMAND, ID_SPCIFICITSDX7D3DIM_CHANGERLERENDERDEVICED3D, 0);
  1205.                 break;
  1206.  
  1207.             case '!':
  1208.                 vCollect();
  1209.                 break;
  1210.  
  1211.             default:
  1212.                 vTrace("Code touche '%c' (%d) reçu", cKey, cKey);
  1213.                 break;
  1214.             }
  1215.         break;
  1216.  
  1217.     case WM_DISPLAYCHANGE:
  1218.         vTrace("*** Changement résolution écran (%d x %d)", LOWORD(lParam), HIWORD(lParam));
  1219.         vRemakeTriview(lParam);
  1220.         break;
  1221.  
  1222.     case WM_CLOSE:
  1223.         DestroyWindow( hWnd );
  1224.         return 0;
  1225.     
  1226.     case WM_DESTROY:
  1227.         PostQuitMessage(0);
  1228.         return 0L;
  1229.     }
  1230.     return DefWindowProc( hWnd, uMsg, wParam, lParam );
  1231. }
  1232.